/* eslint-disable no-plusplus */
/* eslint-disable no-param-reassign */
/* eslint-disable no-case-declarations */
/* eslint-disable import/no-unresolved */
/* eslint-disable import/extensions */
/* eslint-disable import/prefer-default-export */
/* eslint-disable class-methods-use-this */
/* eslint-disable max-classes-per-file */
import Konva from 'konva'
import { IKonvaPen } from '@/components/konvaUnits/tools/IKonvaPen'
import KonvaUtils from '@/components/konvaUnits/utils/konvaUtils'
import { drawFenceGroup } from '@/components/konvaUnits/common/fence'
import { useStore } from '@/store/index'

export class FencesPen implements IKonvaPen {
  status: 'waiting' | 'drawing' | 'disable' = 'waiting'

  points!: number[]

  beginPos!: number[]

  endPos!: number[]

  angle: number = 0

  text: number[] = [0, 0]

  beginPillar!: { id: ''; x: 0; y: 0; rotation: 0; width: 0; height: 0 }

  endPillar!: {
    id: ''
    x: 0
    y: 0
    rotation: 0
    width: 0
    height: 0
  }

  konvaGroup!: Konva.Group

  mousedown(layer: Konva.Layer, points: number[], node: object): void {
    if (points === undefined || this.status === 'disable') return
    switch (this.status) {
      case 'waiting':
        this.status = 'drawing'
        this.beginPos = points
        if (node instanceof Konva.Rect && node.attrs.id.search('pillar') !== -1) {
          this.beginPillar = node.attrs
        } else {
          this.beginPillar = {
            id: '',
            x: this.beginPos[0],
            y: this.beginPos[1],
            rotation: 0,
            width: 0,
            height: 0
          }
        }
        this.konvaGroup = new Konva.Group({ id: 'pen' })
        layer.add(this.konvaGroup)
        break
      case 'drawing':
        this.status = 'waiting'
        this.endPos = points
        if (
          node instanceof Konva.Rect &&
          node.attrs.id.search('pillar') !== -1 &&
          node.attrs.id.search('fenceGroup') !== -1
        ) {
          this.endPillar = node.attrs
          this.endPos = [node.attrs.x, node.attrs.y]
        } else {
          this.endPillar = {
            id: '',
            x: points[0],
            y: points[1],
            rotation: 0,
            width: 0,
            height: 0
          }
          this.endPos = points
        }
        this.points = [this.beginPos[0], this.beginPos[1], this.endPos[0], this.endPos[1]]
        this.konvaGroup.remove()

        this.konvaGroup = new Konva.Group({ id: 'fenceGroup' })
        this.createFence(layer, this.beginPos, this.endPos)
        break
      default:
        break
    }
  }

  mousemove(points: number[], node: object): void {
    const store = useStore()
    if (points === undefined || this.status !== 'drawing') return
    this.konvaGroup.removeChildren()
    this.endPos = points
    if (
      node instanceof Konva.Rect &&
      node.attrs.id.search('pillar') !== -1 &&
      node.attrs.id.search('fenceGroup') !== -1
    ) {
      this.endPillar = node.attrs
      this.endPos = [node.attrs.x, node.attrs.y]
    } else {
      this.endPos = points
      this.endPillar = {
        id: '',
        x: points[0],
        y: points[1],
        rotation: 0,
        width: 0,
        height: 0
      }
    }
    this.createLine(
      'pen',
      this.beginPos,
      this.endPos,
      store.globalParam.plottingScale,
      false,
      store.globalParam.penType === 'sample'
    )
  }

  mouseup(points: number[], node: object): void {}

  clean() {
    this.konvaGroup.remove()
    this.points = [0, 0, 0, 0]
    this.beginPos = [0, 0]
    this.endPos = [0, 0]
    this.status = 'waiting'
  }

  click(e: any): void {
    throw new Error('Method not implemented.')
  }

  createFence(layer: Konva.Layer, start: number[], end: number[]): void {
    this.points = start.concat(end)
    const store = useStore()
    const angle = KonvaUtils.getAngle(start, end)
    if (angle > 0 && angle < 90) this.angle = 0
    else if (angle > 90 && angle < 180) this.angle = 90
    else if (angle < 0 && angle > -90) this.angle = -90
    else if (angle < -90 && angle > -180) this.angle = -180

    const topLength = KonvaUtils.getRealLength(
      KonvaUtils.getPositionLength(start, [end[0], start[1]]),
      store.globalParam.plottingScale
    )
    const leftLength = KonvaUtils.getRealLength(
      KonvaUtils.getPositionLength(start, [start[0], end[1]]),
      store.globalParam.plottingScale
    )
    this.text =
      this.angle === -180 || this.angle === 0 ? [topLength, leftLength] : [leftLength, topLength]
    if (topLength < 200 || leftLength < 200) return

    let id = `fenceGroup${store.drawing.history.size + 1}`
    const fenceTop = drawFenceGroup(
      id,
      [start[0], start[1]],
      topLength,
      0,
      store.globalParam.plottingScale,
      this.beginPillar,
      this.endPillar,
      true
    )
    if (fenceTop.fence !== null) {
      layer.add(fenceTop.fence)
      const children = fenceTop.fence.getChildren().map((child) => {
        return child.id()
      })
      store.drawingAction.setHistory(id, children)
    }

    id = `fenceGroup${store.drawing.history.size + 1}`
    const fenceRight = drawFenceGroup(
      id,
      [fenceTop.points[2], fenceTop.points[3]],
      leftLength,
      90,
      store.globalParam.plottingScale,
      fenceTop.endPillar,
      this.endPillar,
      true
    )
    if (fenceRight.fence !== null) {
      layer.add(fenceRight.fence)
      const children = fenceRight.fence.getChildren().map((child) => {
        return child.id()
      })
      store.drawingAction.setHistory(id, children)
    }
    id = `fenceGroup${store.drawing.history.size + 1}`
    const fenceBottom = drawFenceGroup(
      id,
      [fenceRight.points[2], fenceRight.points[3]],
      topLength,
      180,
      store.globalParam.plottingScale,
      fenceRight.endPillar,
      this.endPillar,
      true
    )
    if (fenceBottom.fence !== null) {
      layer.add(fenceBottom.fence)
      const children = fenceBottom.fence.getChildren().map((child) => {
        return child.id()
      })
      store.drawingAction.setHistory(id, children)
    }
    id = `fenceGroup${store.drawing.history.size + 1}`
    console.log(fenceTop.beginPillar)
    const fenceLeft = drawFenceGroup(
      id,
      [fenceBottom.points[2], fenceBottom.points[3]],
      leftLength,
      -90,
      store.globalParam.plottingScale,
      fenceBottom.endPillar,
      fenceTop.beginPillar,
      true
    )
    if (fenceLeft.fence !== null) {
      layer.add(fenceLeft.fence)
      const children = fenceLeft.fence.getChildren().map((child) => {
        return child.id()
      })
      store.drawingAction.setHistory(id, children)
    }
  }

  createLine(
    id: string,
    start: number[],
    end: number[],
    scale: number,
    addStore: boolean,
    drawLine: boolean
  ) {
    this.points = start.concat(end)
    const angle = KonvaUtils.getAngle(start, end)
    if (angle > 0 && angle < 90) this.angle = 0
    else if (angle > 90 && angle < 180) this.angle = 90
    else if (angle < 0 && angle > -90) this.angle = -90
    else if (angle < -90 && angle > -180) this.angle = -180

    const topLength = KonvaUtils.getRealLength(
      KonvaUtils.getPositionLength(start, [end[0], start[1]]),
      scale
    )
    const leftLength = KonvaUtils.getRealLength(
      KonvaUtils.getPositionLength(start, [start[0], end[1]]),
      scale
    )
    this.text =
      this.angle === -180 || this.angle === 0 ? [topLength, leftLength] : [leftLength, topLength]
    if (!drawLine) {
      if (topLength < 200 || leftLength < 200) return
      const fenceTop = drawFenceGroup(
        id,
        [start[0], start[1]],
        topLength,
        0,
        scale,
        this.beginPillar,
        this.endPillar,
        addStore
      )
      if (fenceTop.fence !== null) this.konvaGroup.add(fenceTop.fence)
      const fenceRight = drawFenceGroup(
        id,
        [fenceTop.points[2], fenceTop.points[3]],
        leftLength,
        90,
        scale,
        fenceTop.endPillar,
        this.endPillar,
        addStore
      )
      if (fenceRight.fence !== null) this.konvaGroup.add(fenceRight.fence)
      const fenceBottom = drawFenceGroup(
        id,
        [fenceRight.points[2], fenceRight.points[3]],
        topLength,
        180,
        scale,
        fenceRight.endPillar,
        this.endPillar,
        addStore
      )
      if (fenceBottom.fence !== null) this.konvaGroup.add(fenceBottom.fence)
      const fenceLeft = drawFenceGroup(
        id,
        [fenceBottom.points[2], fenceBottom.points[3]],
        leftLength,
        -90,
        scale,
        fenceBottom.endPillar,
        fenceTop.beginPillar,
        addStore
      )
      if (fenceLeft.fence !== null) this.konvaGroup.add(fenceLeft.fence)
    } else {
      const fences = new Konva.Rect({
        x: start[0],
        y: start[1],
        width: end[0] - start[0],
        height: end[1] - start[1],
        stroke: 'grey'
      })

      const topText = new Konva.Text({
        x: start[0] + (end[0] - start[0]) / 2 - 10,
        y: start[1],
        text: KonvaUtils.getRealLength(topLength, scale).toString(),
        padding: 2,
        fill: 'black'
      })
      const leftText = new Konva.Text({
        x: start[0],
        y: start[1] + (end[1] - start[1]) / 2,
        text: KonvaUtils.getRealLength(leftLength, scale).toString(),
        padding: 2,
        fill: 'black'
      })
      this.konvaGroup.add(fences, topText, leftText)
    }
  }
}
